﻿from os import path
from codecs import open
from lxml import etree
from decimal import Decimal, ROUND_HALF_UP
from dicts import persons, constants, values
from pypalo.objects import server

def File(b_name, const_name, pers_name, vals_name, year=None):
	"This function generates File element"
	#beginning of function suite
	
	#Создается манипулятор олап сервера
	srv=server("admin", "ivushka2011", None, None, None, "sa-pc247", 7921)
	#Создается словарь олап сервера
	srv_dict=srv.dictionary()
	#Определяется ид базы данных
	base_id=srv_dict["names"][b_name]
	
	#Создается манипулятор базы данных
	db=srv.Database(base_id)
	#Создается словарь базы данных
	db_dict=db.dictionary()

	#Определяется ид измерения Ставка:
	rates_id=db_dict["dims"]["names"]["Ставка"]
	#Создается манипулятор измерения Ставка:
	rates=db.Dimension(rates_id)
	#Создается словарь измерения Ставка:
	rate_name=rates.dictionary()["ids"]
	
	#Определяется ид измерения КодДоход:
	koddohs_id=db_dict["dims"]["names"]["КодДоход"]
	#Создается манипулятор измерения КодДоход:
	koddohs=db.Dimension(koddohs_id)
	#Создается словарь измерения КодДоход:
	koddoh_name=koddohs.dictionary()["ids"]
	
	#Определяется ид измерения КодВычет:
	kodvics_id=db_dict["dims"]["names"]["КодВычет"]
	#Создается манипулятор измерения КодВычет:
	kodvics=db.Dimension(kodvics_id)
	#Создается словарь измерения КодВычет:
	kodvic_name=kodvics.dictionary()["ids"]

	#Определяется ид измерения Месяц:
	months_id=db_dict["dims"]["names"]["Месяц"]
	#Создается манипулятор измерения Месяц:
	months=db.Dimension(months_id)
	#Создается словарь измерения Месяц:
	month_name=months.dictionary()["ids"]
	
	cons=constants(b_name, const_name, year)
	pers=persons(b_name, pers_name, year)
	
	# Файл
	_File=etree.Element("Файл", nsmap = {"xsi" : cons['xsi']})
	_File.attrib["ИдФайл"]=cons["ИдФайл"]
	_File.attrib["ВерсПрог"]=cons["ВерсПрог"]
	_File.attrib["ВерсФорм"]=cons["ВерсФорм"]
		# СвРекв
	_File_SvReqv=etree.SubElement(_File, "СвРекв")
	_File_SvReqv.attrib["ОКАТО"]=cons["ОКАТО"]
	_File_SvReqv.attrib["ОтчетГод"]=cons["ОтчетГод"]
	_File_SvReqv.attrib["ПризнакФ"]=cons["ПризнакФ"]
			# СвЮЛ
	_File_SvReqv_SvUL=etree.SubElement(_File_SvReqv, "СвЮЛ")
	_File_SvReqv_SvUL.attrib["ИННЮЛ"]=cons["ИННЮЛ"]
	_File_SvReqv_SvUL.attrib["КПП"]=cons["КПП"]
	
		# Документ
	count=0
	vals=values(b_name, vals_name, pers, year)
	
	for val in vals:
		Doc(_File, cons, val, rate_name, koddoh_name, kodvic_name, month_name)
		count+=1
	
	#end of function suite
	return [_File, count, _File.attrib["ИдФайл"]]

def Doc(_File, cons, person, rate_name, koddoh_name, kodvic_name, month_name):
	"This function generates documnet elements"
	#beginning of function suite
	
	
	#Документ
	_Doc=etree.SubElement(_File, "Документ")
	_Doc.attrib["КНД"]=cons["КНД"]
	_Doc.attrib["ДатаДок"]=cons["ДатаДок"]
	_Doc.attrib["ОтчетГод"]=cons["ОтчетГод"]
	_Doc.attrib["НомСпр"]=person["requisites"]["НомСпр"]
	_Doc.attrib["Признак"]=cons["Признак"]
	_Doc.attrib["КодНО"]=cons["КодНО"]

		#СвНА
	_Doc_SvNA=etree.SubElement(_Doc, "СвНА")
	_Doc_SvNA.attrib["ОКАТО"]=cons["ОКАТО"]
	_Doc_SvNA.attrib["Тлф"]=cons["Тлф"]
	
			# СвНАЮЛ
	_Doc_SvNA_SvNAUL=etree.SubElement(_Doc_SvNA, "СвНАЮЛ")
	_Doc_SvNA_SvNAUL.attrib["НаимОрг"]=cons["НаимОрг"]
	_Doc_SvNA_SvNAUL.attrib["ИННЮЛ"]=cons["ИННЮЛ"]
	_Doc_SvNA_SvNAUL.attrib["КПП"]=cons["КПП"]

	

		# ПолучДох
	_Doc_PoluchDoh=etree.SubElement(_Doc, "ПолучДох")
	for item in ["ИННФЛ", "Статус", "ДатаРожд", "Гражд"]:
		if item in person["requisites"]:
			_Doc_PoluchDoh.attrib[item]=person["requisites"][item]

			# ФИО
	_Doc_PoluchDoh_FIO=etree.SubElement(_Doc_PoluchDoh, "ФИО")
	for item in ["Фамилия", "Имя", "Отчество"]:
		if item in person["requisites"]:
			_Doc_PoluchDoh_FIO.attrib[item]=person["requisites"][item]

			# УдЛичнФЛ
	_Doc_PoluchDoh_UdLicnFL=etree.SubElement(_Doc_PoluchDoh, "УдЛичнФЛ")
	for item in ["КодУдЛичн", "СерНомДок"]:
		if item in person["requisites"]:
			_Doc_PoluchDoh_UdLicnFL.attrib[item]=person["requisites"][item]

			# АдрМЖРФ

	_Doc_PoluchDoh_AdrMZRF=etree.SubElement(_Doc_PoluchDoh, "АдрМЖРФ")
	for item in ["Индекс", "КодРегион", "Район", "Город", "НаселПункт", "Улица", "Дом", "Корпус", "Кварт"]:
		if item in person["requisites"]:
			_Doc_PoluchDoh_AdrMZRF.attrib[item]=person["requisites"][item]
			
			# АдрИНО

	_Doc_PoluchDoh_AdrINO=etree.SubElement(_Doc_PoluchDoh, "АдрИНО")
	for item in ["КодСтр", "АдрТекст"]:
		if item in person["requisites"]:
			_Doc_PoluchDoh_AdrINO.attrib[item]=person["requisites"][item]

		# СведДох
	for rate in list(person["rates"]):
		
		_Doc_SvedDoh=etree.SubElement(_Doc, "СведДох")
		_Doc_SvedDoh.attrib["Ставка"]=rate_name[rate]
		
			# ДохВыч
		_Doc_SvedDoh_DohVic=etree.SubElement(_Doc_SvedDoh, "ДохВыч")
		
		for month in list(person["rates"][rate]["months"]):
			for koddoh in list(person["rates"][rate]["months"][month]["koddohs"]):
				# СвСумДох
				_Doc_SvedDoh_DohVic_SvSumDoh=etree.SubElement(_Doc_SvedDoh_DohVic, "СвСумДох")
				_Doc_SvedDoh_DohVic_SvSumDoh.attrib["Месяц"]=month_name[month]
				_Doc_SvedDoh_DohVic_SvSumDoh.attrib["КодДоход"]=koddoh_name[koddoh]
				_Doc_SvedDoh_DohVic_SvSumDoh.attrib["СумДоход"]=str(Decimal(person["rates"][rate]["months"][month]["koddohs"][koddoh]["СумДоход"]).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
					# СвСумВыч
				_Doc_SvedDoh_DohVic_SvSumDoh_SvSumVic=etree.SubElement(_Doc_SvedDoh_DohVic_SvSumDoh, "СвСумВыч")
				_Doc_SvedDoh_DohVic_SvSumDoh_SvSumVic.attrib["КодВычет"]=person["rates"][rate]["months"][month]["koddohs"][koddoh]["КодВычет"]
				_Doc_SvedDoh_DohVic_SvSumDoh_SvSumVic.attrib["СумВычет"]=str(Decimal(person["rates"][rate]["months"][month]["koddohs"][koddoh]["СумВычет"]).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))

			# НалВычССИ
		_Doc_SvedDoh_NalVicSSI=etree.SubElement(_Doc_SvedDoh, "НалВычССИ")

		for kodvic in list(person["rates"][rate]["kodvics"]):
				# ПредВычССИ
			_Doc_SvedDoh_NalVicSSI_PredVicSSI=etree.SubElement(_Doc_SvedDoh_NalVicSSI, "ПредВычССИ")
			_Doc_SvedDoh_NalVicSSI_PredVicSSI.attrib["КодВычет"]=kodvic_name[kodvic]
			_Doc_SvedDoh_NalVicSSI_PredVicSSI.attrib["СумВычет"]=str(Decimal(person["rates"][rate]["kodvics"][kodvic]["СумВычет"]).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))

	# SumDohObc, NalBaza

		SumDohObc=Decimal(0)
		for item in _Doc_SvedDoh_DohVic:
			SumDohObc+=Decimal(item.attrib["СумДоход"])
			SumDohObc=SumDohObc.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
		
		NalBaza=SumDohObc
		for item in _Doc_SvedDoh_DohVic:
			for subitem in item:
				NalBaza-=Decimal(subitem.attrib["СумВычет"])
		for item in _Doc_SvedDoh_NalVicSSI:
			NalBaza-=Decimal(item.attrib["СумВычет"])
		NalBaza=NalBaza.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
		
		
		NalIscisl=((Decimal(rate_name[rate])/100)*NalBaza).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
		
		NalUderz=Decimal(person['rates'][rate]['taxed']).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
		
		NalPerecisl=(NalIscisl*(Decimal(cons['ProcUpl'])/100)).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
		
		if NalUderz>NalIscisl:
			NalUderzLis=NalUderz-NalIscisl
			NalNeUderz=0
		else:
			NalNeUderz=NalIscisl-NalUderz
			NalUderzLis=0


			# СГДНалПер
		_Doc_SvedDoh_SGDNalPer=etree.SubElement(_Doc_SvedDoh, "СГДНалПер")
		_Doc_SvedDoh_SGDNalPer.attrib["СумДохОбщ"]=str(SumDohObc)
		_Doc_SvedDoh_SGDNalPer.attrib["НалБаза"]=str(NalBaza)
		_Doc_SvedDoh_SGDNalPer.attrib["НалИсчисл"]=str(NalIscisl)
		_Doc_SvedDoh_SGDNalPer.attrib["НалУдерж"]=str(NalUderz)
		_Doc_SvedDoh_SGDNalPer.attrib["НалПеречисл"]=str(NalPerecisl)
		_Doc_SvedDoh_SGDNalPer.attrib["НалУдержЛиш"]=str(NalUderzLis)
		_Doc_SvedDoh_SGDNalPer.attrib["НалНеУдерж"]=str(NalNeUderz)
		
	#end of function suite
	#return _Doc
	print(person['fiotab'])
	#print(person["requisites"]["НомСпр"])
	return

def reader(root):
	"This function returns strings from root object"
	#beginning of function suite
	#end of function suite
	return etree.tostring(root, pretty_print=True, encoding='windows-1251').decode('cp1251')

def indenter(string):
	pos=string.index('<')
	string='\t'*int(pos/2)+string[pos:]
	return string

def corrector(strings):
	newstrings=''
	skiplist=['<АдрИНО/>', '<НалВычССИ/>', '''<СвСумВыч КодВычет="0" СумВычет="0.00"/>''']
	for string in strings.splitlines():
		skipcount=0
		for item in skiplist:
			if item in string:
				skipcount+=1
		if skipcount==0:
			string=indenter(string)+'\r\n'
			newstrings+=string
	return newstrings

def writer(strings, end):
	"This function writes strings to xml"
	#beginning of function suite
	count=len(strings)
	endfile = open(path.abspath(end), 'w+', 'cp1251')
	endfile.write(strings)
	endfile.close()
	#end of function suite
	return count